package de.hauschild.dbc4j.aspects;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.PredicateUtils;

import de.hauschild.dbc4j.util.ReflectionUtils;

/**
 * The abstract aspect gives simple access to all annotations for a given {@link Method} with a concrete annotation
 * type.
 * 
 * @since 1.0.0
 * @author Hauschild
 */
public abstract class AbstractConditionAspect {

  /**
   * Returns all {@link Annotation Annotations} for the {@link Method} with the specified type.
   * 
   * @param <T>
   *          the concrete type of the annotation
   * @param method
   *          the method
   * @param annotationType
   *          the annotation type
   * @return the annotations
   */
  @SuppressWarnings("unchecked")
  protected <T extends Annotation> Set<T> getAnnotationFrom(final Method method, final Class<T> annotationType) {
    // collect all annotation of method
    final Set<Annotation> annotations = ReflectionUtils.getAnnotations(method);
    // filter annotations
    final Set<Annotation> filteredAnnotations = new HashSet<Annotation>(annotations);
    CollectionUtils.filter(filteredAnnotations, PredicateUtils.instanceofPredicate(annotationType));
    // convert result
    final Set<T> result = new HashSet<T>();
    for (final Annotation annotation : filteredAnnotations) {
      result.add((T) annotation);
    }
    // return result
    return result;
  }
}
